home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Graphics 2D / Out of This GWorld / out.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  16.6 KB  |  504 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        out.c
  3.  
  4.     Contains:    This application demonstrates one method to                    
  5.                 produce animation on the Macintosh using QuickDraw's        
  6.                 palette manager animation routines.  The app simply            
  7.                 creates an offscreen image, copies it to the                
  8.                 screen's window, then calls AnimatePalette()                
  9.                 every cycle through the eventloop.  To provide the            
  10.                 fastest possible animation, the image is only                
  11.                 created and copied once from the offscreen GWorld.            
  12.                 The actual animation is produced by shifting the            
  13.                 color entries within its colortable forward or                
  14.                 backward one index.  Also the cTable is divided                
  15.                 and shifted in two separate groups to simulate                
  16.                 objects moving at different speeds.            
  17.  
  18.     Written by: EL    
  19.  
  20.     Copyright:    Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved.
  21.  
  22.                 You may incorporate this Apple sample source code into your program(s) without
  23.                 restriction. This Apple sample source code has been provided "AS IS" and the
  24.                 responsibility for its operation is yours. You are not permitted to redistribute
  25.                 this Apple sample source code as "Apple sample source code" after having made
  26.                 changes. If you're going to re-distribute the source, we require that you make
  27.                 it clear in the source that the code was descended from Apple sample source
  28.                 code, but that you've made changes.
  29.  
  30.     Change History (most recent first):
  31.                 08/2000        JM                Carbonized, non-Carbon code is commented out
  32.                                             for demonstration purposes.
  33.                 7/16/1999    KG                Updated for Metrowerks Codewarror Pro 2.1
  34.                 
  35.  
  36. */
  37.  
  38. #include "out.h"
  39.  
  40. /*******************************/
  41. /* Global Variable Definitions */
  42. /*******************************/
  43.  
  44. WindowPtr        gWindow;                /* Main Display Window */
  45. CTabHandle        gCTable;                /* Window & offscreen Colortable */
  46. GWorldPtr        gGWorld;                /* Offscreen GWorld */
  47. PixMapHandle    gPixMap;                /* PixMap of the GWorld */
  48. PaletteHandle    gPalette;                /* Window & offscreen Palette */
  49.  
  50. int                gCurrentPat = 1;        /* Current Test Pattern */
  51. int                gCurrentMove = STOP;    /* Current State of Animation */
  52. int                gCurrentDir = FORWARD;    /* Current Direction to Shift Palette Colors */
  53. int                gCurrentColor = COLOR;    /* Current Colors: mixed or gray */
  54.  
  55. void main(void)
  56. {
  57.     //MaxApplZone();            /* Increase application heap. */
  58.  
  59.     initMac();                /* Do standard mac initializations. */
  60.     initVariables();        /* Initialize the colortable. */
  61.     
  62.     createWindow();
  63.     createPalette();
  64.     createGWorld();
  65.  
  66.     createImage();            /* Create the current image offscreen. */
  67.     drawImage();            /* Copybits the offscreen image into the window. */
  68.  
  69.     pollEvents();            /* Handle any events & update the palette. */
  70. }
  71.  
  72. void initMac()
  73. {
  74.     /*********************************/
  75.     /* Standard Initialization Calls */
  76.     /*********************************/
  77.     
  78.     /*InitGraf( &qd.thePort );
  79.     InitFonts();
  80.     InitWindows();
  81.     InitMenus();
  82.     TEInit();
  83.     InitDialogs( nil );*/
  84.     InitCursor();
  85.     FlushEvents( 0, everyEvent );
  86.     
  87.     setUpMenus();
  88. }
  89.  
  90. void initVariables()
  91. {
  92.     /********************************************************************/
  93.     /* Allocate memory for the colortable.  Since ColorTable already    */
  94.     /*    contains one ColorSpec, allocate (TOTALCOLORS - 1) ColorSpec's.    */
  95.     /*    One ColorSpec is required for each entry.                        */
  96.     /********************************************************************/
  97.         
  98.     gCTable = (CTabHandle)NewHandle( sizeof( ColorTable ) +
  99.                 ((TOTALCOLORS - 1) * sizeof( ColorSpec )));
  100. }
  101.  
  102. void createWindow()
  103. {
  104.     Rect wBounds;
  105.     BitMap    bitMap;
  106.     int    top, left;
  107.     
  108.     GetQDGlobalsScreenBits(&bitMap);
  109.     
  110.     top = (((bitMap.bounds.bottom - bitMap.bounds.top) - WHEIGHT) / 2);
  111.     left = (((bitMap.bounds.right - bitMap.bounds.left) - WWIDTH) / 2);
  112.  
  113.     /*****************************************************************/    
  114.     /* Create and center the destination window in the main monitor. */
  115.     /*****************************************************************/
  116.     
  117.     //SetRect( &wBounds, WLEFT, WTOP, WLEFT + WWIDTH, WTOP + WHEIGHT );
  118.     SetRect( &wBounds, left, top, left + WWIDTH, top + WHEIGHT );
  119.     gWindow = NewCWindow( 0L, &wBounds, "\pOut of This GWorld", true, noGrowDocProc,
  120.                             (WindowPtr)-1L, true, 0L );
  121.     
  122.     /**************************************************************/
  123.     /* Display the main window and assign it as the current port. */
  124.     /**************************************************************/
  125.     
  126.     ShowWindow( gWindow );
  127.     //SetPort( gWindow );
  128.     SetPortWindowPort( gWindow );
  129. }
  130.  
  131. void createPalette()
  132. {
  133.     /********************************************************************/
  134.     /* Allocate a palette for color animation.  Using pmExplicit as the    */
  135.     /*    usage, tells QD that the index values in the palette are more    */
  136.     /*    important than the rgb values stored at that index.  This is    */
  137.     /*    necessary since the animation in this application is simulated    */
  138.     /*    by shifting the colors at each palette index.                    */
  139.     /********************************************************************/
  140.     
  141.     gPalette = NewPalette( TOTALCOLORS, nil, pmAnimated + pmExplicit, 0 );
  142.     
  143.     /************************************************/
  144.     /* Define the rgb values at each palette index. */
  145.     /************************************************/
  146.     
  147.     defineColorPalette();
  148.     
  149.     /******************************************/
  150.     /* Attach the palette to the main window. */
  151.     /******************************************/
  152.     
  153.     SetPalette( gWindow, gPalette, true );
  154. }
  155.  
  156. void createGWorld()
  157. {
  158.     int            i;
  159.     Rect        gBounds;
  160.     Rect        tempRect1;
  161.     //CGrafPtr    currentPort;
  162.     //GDHandle    currentDevice;
  163.     
  164.     /*************************************************/
  165.     /* Define the size of the GWorld's bounding box. */
  166.     /*************************************************/
  167.     
  168.     /*SetRect( &gBounds, 0, 0, gWindow->portRect.right - gWindow->portRect.left,
  169.                             gWindow->portRect.bottom - gWindow->portRect.top );*/
  170.     GetPortBounds(GetWindowPort(gWindow), &tempRect1);
  171.     
  172.     SetRect( &gBounds, 0, 0, tempRect1.right - tempRect1.left, tempRect1.bottom - tempRect1.top );
  173.  
  174.     /********************************************************************************/
  175.     /* Convert the palette to a colortable before explicitly setting bit 14 in        */
  176.     /*    the ctFlags field of the colortable.  This tells the colortable to refer    */
  177.     /*    to the palette indexes instead of its rgb values.  Again, this is             */
  178.     /*    necessary since the animation is performed by altering the palette.            */
  179.     /********************************************************************************/
  180.         
  181.     Palette2CTab( gPalette, gCTable );
  182.     (**gCTable).ctFlags |= 0x4000;
  183.  
  184.     /************************************************************************/
  185.     /* Make sure each value field of the colortable is assigned to the        */
  186.     /*    corresponding entry in the palette and make sure the ctSeed field    */
  187.     /*    is given a unique value.                                            */
  188.     /************************************************************************/
  189.     
  190.     for (i = 0; i < TOTALCOLORS; i++)
  191.         (**gCTable).ctTable[i].value = i;
  192.     (**gCTable).ctSeed = GetCTSeed();
  193.     
  194.     /*************************************************************************/
  195.     /* Allocate a new GWorld for the offscreen drawing and store its PixMap. */
  196.     /*************************************************************************/
  197.     
  198.     NewGWorld( &gGWorld, 8, &gBounds, gCTable, nil, 0 );
  199.     gPixMap = GetGWorldPixMap( gGWorld );
  200. }
  201.  
  202. void updatePalette()
  203. {
  204.     /******************************************************************************/
  205.     /* Convert the altered colortable to a palette, then animate all its entries. */
  206.     /******************************************************************************/
  207.  
  208.     Palette2CTab( gPalette, gCTable );
  209.     AnimatePalette( gWindow, gCTable, 0, 0, TOTALCOLORS );
  210. }
  211.  
  212. void defineColorPalette()
  213. {
  214.     int i;
  215.     
  216.     gCurrentColor = COLOR;
  217.  
  218.     /***********************************************************************/
  219.     /* Define the first 8 palette entries with primary & secondary colors. */
  220.     /***********************************************************************/
  221.     
  222.     setRGB( 0, 0, 0, 0 );            /* black */
  223.     setRGB( 1, 0, 255, 0 );            /* green */
  224.     setRGB( 2, 0, 255, 255 );        /* cyan */
  225.     setRGB( 3, 0, 0, 255 );            /* blue */
  226.     setRGB( 4, 255, 0, 255 );        /* magenta */
  227.     setRGB( 5, 255, 0, 0 );            /* red */
  228.     setRGB( 6, 255, 255, 0 );        /* yellow */
  229.     setRGB( 7, 255, 255, 255 );        /* white */
  230.  
  231.     /*******************************************************************/
  232.     /* Define shades of the previous colors for the remaining entries. */
  233.     /*******************************************************************/
  234.  
  235.     for (i = 8; i < 48; i++)                                        /* greens */
  236.         setRGB( i, 0, 10 + ((i - 8) * 6), 0 );
  237.         
  238.     for (i = 48; i < 88; i++)                                        /* blues */
  239.         setRGB( i, 0, 0, 10 + ((i - 48) * 6) );
  240.         
  241.     for (i = 88; i < 128; i++)                                        /* reds */
  242.         setRGB( i, 10 + ((i - 88) * 6), 0, 0 );
  243.     
  244.     for (i = 128; i < 168; i++)                                        /* magentas */
  245.         setRGB( i, 10 + ((i - 128) * 6), 0, 10 + ((i - 128) * 6) );
  246.     
  247.     for (i = 168; i < 208; i++)                                        /* yellows */
  248.         setRGB( i, 10 + ((i - 168) * 6), 10 + ((i - 168) * 6), 0 );
  249.     
  250.     for (i = 208; i < 248; i++)                                        /* cyans */
  251.         setRGB( i, 0, 10 + ((i - 208) * 6), ((i - 208) * 6) );
  252. }
  253.  
  254. void defineGrayPalette()
  255. {
  256.     int i;
  257.     int shade;
  258.  
  259.     gCurrentColor = GRAY;
  260.     
  261.     /*******************************************************/
  262.     /* Define all the palette entries with shades of gray. */
  263.     /*******************************************************/
  264.  
  265.     for (i = 1; i < 7; i++)
  266.     {
  267.         shade = i * 42;
  268.         setRGB( i, shade, shade, shade );
  269.     }
  270.     
  271.     for (i = 8, shade = 10; i < 248; i++)
  272.     {
  273.         setRGB( i, shade, shade, shade );
  274.         shade += 12;
  275.         
  276.         if ((i - 8) % 20 == 0)
  277.             shade = 10;
  278.     }
  279. }
  280.  
  281. void setRGB( index, r, g, b )
  282. int    index;
  283. int    r, g, b;
  284. {
  285.     RGBColor aColor;
  286.     
  287.     /***********************************************************************/
  288.     /* Set the rgb values for the palette color stored at the index value. */
  289.     /***********************************************************************/
  290.     
  291.     aColor.red = r * SUN2MAC;        /* All colors were defined using    */
  292.     aColor.green = g * SUN2MAC;        /*    SUN computer raster values.        */
  293.     aColor.blue = b * SUN2MAC;
  294.     
  295.     SetEntryColor( gPalette, index, &aColor );
  296. }
  297.  
  298. void setColor( index )
  299. int index;
  300. {
  301.     RGBColor aColor;
  302.     
  303.     /********************************************************/
  304.     /* Get the rgb values stored at the index value in the    */
  305.     /*    palette, then use it as the foreground color.        */
  306.     /********************************************************/
  307.                     
  308.     GetEntryColor( gPalette, index, &aColor );
  309.     RGBForeColor( &aColor );
  310. }
  311.  
  312. void createImage()
  313. {
  314.     CGrafPtr    currentPort;
  315.     GDHandle    currentDevice;
  316.     RGBColor    aColor;
  317.     
  318.     /******************************************************************************/
  319.     /* Store the current port and device before switching to the offscreen world. */
  320.     /******************************************************************************/
  321.     
  322.     GetGWorld( ¤tPort, ¤tDevice );
  323.     
  324.     /****************************************************************************/
  325.     /* Switch to the offscreen GWorld then lock the offscreen buffer in memory. */
  326.     /****************************************************************************/
  327.  
  328.     SetGWorld( gGWorld, nil );
  329.     LockPixels( gPixMap );
  330.     
  331.     /************************************************/
  332.     /* Set the background color to black then erase    */
  333.     /*    the PixMap's bounding box in the GWorld.    */
  334.     /************************************************/
  335.     
  336.     GetEntryColor( gPalette, 0, &aColor );
  337.     RGBBackColor( &aColor );
  338.     EraseRect( &(**gPixMap).bounds );
  339.  
  340.     /*************************************************************/
  341.     /* Draw a 1 pixel wide white border along the PixMap's edge. */
  342.     /*************************************************************/
  343.     
  344.     drawWindowBorder();
  345.  
  346.     /*************************************************************************/
  347.     /* Depending on the current test pattern, create an image in the PixMap. */
  348.     /*************************************************************************/
  349.  
  350.     if (gCurrentPat == 1)
  351.         createColorScale();
  352.     else if (gCurrentPat == 2)
  353.         createColorWheels();
  354.     else if (gCurrentPat == 3)
  355.         createColorRings();
  356.     else if (gCurrentPat == 4)
  357.         createColorGears();
  358.     else if (gCurrentPat == 5)
  359.         createColorCurves();
  360.     else if (gCurrentPat == 6)
  361.         createColorBalls();
  362.     else if (gCurrentPat == 7)
  363.         createColorWave();
  364.     else if (gCurrentPat == 8)
  365.         createColorText();
  366.     else
  367.         doAbout();                /* Treat the About message as a test pattern. */
  368.     
  369.     /********************************************************************/
  370.     /* After drawing the image, unlock the offscreen buffer in memory    */
  371.     /*    and set the port and device back to the window's.                */
  372.     /********************************************************************/
  373.  
  374.     UnlockPixels( gPixMap );
  375.     SetGWorld( currentPort, currentDevice );
  376. }
  377.  
  378. void drawWindowBorder()
  379. {
  380.     /********************************************************************/
  381.     /* Set the foreground color to white before drawing a 1 pixel wide    */
  382.     /*    frame around the PixMap's bounding box.                            */
  383.     /********************************************************************/
  384.     
  385.     setColor( 7 );
  386.     PenSize( 1, 1 );
  387.     MoveTo( 0, 0 );
  388.     LineTo( 0, (**gPixMap).bounds.bottom - 1 );
  389.     LineTo( (**gPixMap).bounds.right - 1, (**gPixMap).bounds.bottom - 1 );
  390.     LineTo( (**gPixMap).bounds.right - 1, 0 );
  391. }
  392.  
  393. void drawImage()
  394. {
  395.     Rect    tempRect1;
  396.     
  397.     /***********************************************************/
  398.     /* Transfer the contents of the PixMap to the main window. */
  399.     /***********************************************************/
  400.  
  401.     /*CopyBits( (BitMap*)*gPixMap, &gWindow->portBits, &(**gPixMap).bounds,
  402.                 &gWindow->portRect, srcCopy, 0l);*/
  403.     CopyBits( (BitMap *)*gPixMap, GetPortBitMapForCopyBits(GetWindowPort(gWindow)), &(**gPixMap).bounds,
  404.                 GetPortBounds(GetWindowPort(gWindow), &tempRect1), srcCopy, 0L);
  405. }
  406.  
  407. void animateCTable()
  408. {
  409.     static int        counter = 0;
  410.     RGBColor         aColor;
  411.  
  412.     /**************************************************************************/
  413.     /* Convert the Palette to a colortable before shifting the color entries. */
  414.     /**************************************************************************/
  415.     
  416.     Palette2CTab( gPalette, gCTable );    
  417.  
  418.     /************************************************************************/
  419.     /* Depending on the current direction, shift 239 palette entries either    */
  420.     /*    ahead 1 or behind 1 index.  Store the first or last entry before    */
  421.     /*    shifting to avoid overwriting its rgb values.                        */
  422.     /************************************************************************/
  423.  
  424.     if (gCurrentDir == FORWARD)
  425.     {
  426.         aColor = (**gCTable).ctTable[247].rgb;
  427.         BlockMove( &(**gCTable).ctTable[8].value, &(**gCTable).ctTable[9].value,
  428.                     239 * sizeof(ColorSpec) );
  429.         (**gCTable).ctTable[8].rgb = aColor;
  430.     }
  431.     else
  432.     {
  433.         aColor = (**gCTable).ctTable[8].rgb;
  434.         BlockMove( &(**gCTable).ctTable[9].value, &(**gCTable).ctTable[8].value,
  435.                     239 * sizeof(ColorSpec) );
  436.         (**gCTable).ctTable[247].rgb = aColor;
  437.     }
  438.     
  439.     /**************************************************************/
  440.     /* Shift the first 5 colortable entries once every 6 updates. */
  441.     /**************************************************************/
  442.     
  443.     if (counter == 0)
  444.     {
  445.         aColor = (**gCTable).ctTable[1].rgb;
  446.         BlockMove( &(**gCTable).ctTable[2].value, &(**gCTable).ctTable[1].value,
  447.                     5 * sizeof(ColorSpec) );
  448.         (**gCTable).ctTable[6].rgb = aColor;
  449.     }
  450.  
  451.     /********************************************************/
  452.     /* Update the window's colors by passing the new        */
  453.     /*    colortable as the srcCTab field of AnimatePalette.    */
  454.     /********************************************************/
  455.     
  456.     AnimatePalette( gWindow, gCTable, 0, 0, TOTALCOLORS );
  457.     
  458.     /**********************************************/
  459.     /* Increment the counter by 1 on each update. */
  460.     /**********************************************/
  461.     
  462.     counter = (counter + 1) % 6;
  463. }
  464.  
  465. void doAbout()
  466. {
  467.     Rect        rect;
  468.     PicHandle    thePict;
  469.     int            width, height;
  470.     
  471.     /*******************************************************/
  472.     /* Load the About picture stored in the resource fork. */
  473.     /*******************************************************/
  474.  
  475.     thePict = (PicHandle)GetResource( 'PICT', 128 );
  476.     
  477.     /************************************************/
  478.     /* Define the rect used to enclose the picture. */
  479.     /************************************************/
  480.  
  481.     width = (**thePict).picFrame.right - (**thePict).picFrame.left;
  482.     height = (**thePict).picFrame.bottom - (**thePict).picFrame.top;
  483.  
  484.     SetRect( &rect, (WWIDTH - width) / 2, (WHEIGHT - height) / 2, 
  485.                     ((WWIDTH - width) / 2) + width, ((WHEIGHT - height) / 2 ) + height );
  486.  
  487.     /*********************************/
  488.     /* Draw the picture in the rect. */
  489.     /*********************************/
  490.  
  491.     DrawPicture( thePict, &rect );
  492.     ReleaseResource( (Handle)thePict );
  493. }
  494.  
  495. void cleanUp()
  496. {
  497.     /*****************************************************************************/
  498.     /* Free the memory set aside for the GWorld and main window before exitting. */
  499.     /*****************************************************************************/
  500.  
  501.     DisposeGWorld( gGWorld );
  502.     DisposeWindow( gWindow );
  503.     ExitToShell();
  504. }